package com.my.main.common.encrypt;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.crypto.*;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.kerberos.KerberosPrincipal;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;


/**
 * @author 韩晗	2015-10-15
 */
public class DES {

	
	// 用于产生指定key的常量定义---开始
	private static final String 	ALGORITHM_NAME  = "DES";		// 算法名称
	private static final String[] 	PRINCIPAL_NAMES = {				// 公钥
												"ZhuMinghui   @qces.cn", // 权限码加密
												"LiuPengcheng @qces.cn", // 角色成员加密
												"WangGuoqing  @qces.cn", 
												"GuoJunhai    @qces.cn"
											};
	private static final String[] 	KEY_PASSWORDS   = {				// 私钥
												"anjingdemeinanzi", 
												"lachouhen", 
												"yangyule", 
												"xinchengxuyuan"
											};
	
	protected static Log logger = LogFactory.getLog(DES.class);

	
	// 用于产生指定的key的常量定义--结束
	public static void main(String args[]) {
//		String codes = ",SYS,SYS_plat,SYS_plat_set,SYS_plat_set_01,SYS_plat_set_02,SYS_plat_user,SYS_plat_user_01,SYS_plat_user_02,";
//		String users = ",1,";
//		try {
//			codes = encrypt(codes, 0, 1L);
//			users = encrypt(users, 1, 1L);
//			System.out.println(codes);
//			System.out.println(users);
//			
//			System.out.println(decrypt(codes, 0, 1L));
//		}
//		catch (Exception e) {
//			e.printStackTrace();
//		}
	}
	
	
	/**
	 * 加密字符串
	 * @param enc		明文
	 * @param index		秘钥组编号0-3
	 * 					0 对权限码加密
	 * 					1 对权限用户加密
	 * @param dynId		动态私钥ID
	 * @return
	 */
	public static String encrypt(String enc, int index, Object dynId) {
		try {
			return new DES().encrypt(enc, PRINCIPAL_NAMES[index], KEY_PASSWORDS[index]+String.valueOf(dynId));
		}
		catch(Exception e) {
			logger.error(e);
			return null;
		}
	}
	
	
	/**
	 * 解密字符串
	 * @param dec		密文
	 * @param index		秘钥组编号0-3
	 * 					0 对权限码加密
	 * 					1 对权限用户加密
	 * @return
	 */
	public static String decrypt(String dec, int index, Object dynId) {
		try {
			return new DES().decrypt(dec, PRINCIPAL_NAMES[index], KEY_PASSWORDS[index]+String.valueOf(dynId));
		}
		catch(Exception e) {
			logger.error(e);
			return null;
		}
	}
	

	
	
	/**
	 * DES加密字符串，返回加密后的字符串
	 * 
	 * @param encryptString
	 *            要加密的字符串
	 * @param strings
	 *            不传此参数按默认生成密钥 参数数组，[0]=加密主体名称，[1]=key的密码
	 * @return 返回base64转码后的字符串
	 * @throws InvalidKeyException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws UnsupportedEncodingException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	public String encrypt(String encryptString, String... strings)
			throws InvalidKeyException, NoSuchAlgorithmException,
			 				NoSuchPaddingException, UnsupportedEncodingException,
			 						IllegalBlockSizeException, BadPaddingException {
	
		 Key key = createKey(strings);
		 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		 byte[] by = encryptString.getBytes("utf-8");
		 cipher.init(Cipher.ENCRYPT_MODE, key);// 使用私鈅加密
		 byte[] cipherText = cipher.doFinal(by);
		 return Base64.encode(cipherText).replaceAll("\n", "");
	}
	
	/**
	 * DES解密字符串
	 * 
	 * @param decryptString要解密的字符串
	 * @param strings生成密鑰的參數
	 *            不传此参数按默认生成密钥 参数数组，[0]=加密主体名称，[1]=key的密码
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchPaddingException
	 * @throws UnsupportedEncodingException
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	public String decrypt(String decryptString, String... strings)
					throws NoSuchAlgorithmException, NoSuchPaddingException,
							UnsupportedEncodingException, InvalidKeyException,
								IllegalBlockSizeException, BadPaddingException {

		Key key = createKey(strings);
		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		byte[] by = Base64.decode(decryptString);
		cipher.init(Cipher.DECRYPT_MODE, key);// 使用私鈅加密
		byte[] cipherText = cipher.doFinal(by);
		return new String(cipherText, "utf-8");
	}
	
	/**
	 * 创建指定的key，参数数组含义： strings[0]=生成key的主体名称
	 * strings[1]=key的密码（参考命名格式xxx@xx.xxx其他命名格式参考Java Cryptography Architecture
	 * API Specification & Reference 中的附录 A） strings[2]=算法名称如果不传参数按默认值
	 * 
	 * @param strings
	 * @return
	 */
	public static Key createKey(String... strings) {
		String algorithm 	= ALGORITHM_NAME;
		String name 		= PRINCIPAL_NAMES[0];
		String password 	= KEY_PASSWORDS[0];
		switch (strings.length) {
	  		case 1:
	  			name = strings[0];
	  			break;
		  	case 2:
		  		name = strings[0];
		  		password = strings[1];
		  		break;
		  	case 3:
		  		name = strings[0];
		  		password = strings[1];
		  		algorithm = strings[2];
		  		break;
		}

		KerberosPrincipal kerberosPrincipal = new KerberosPrincipal(name);
		Key key = new KerberosKey(kerberosPrincipal, password.toCharArray(), algorithm);
		return key;
	}

	/**
	 * 产生一个随机key，并保存到文件中
	 * 
	 * @param file
	 */
	public static void setPriveKey(String file) {
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(file);
			KeyGenerator keyGen = KeyGenerator.getInstance("DES");
			keyGen.init(56);
			Key key = keyGen.generateKey();// 生成私钥Key
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(key);
			oos.close();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * 从文件中获取key
	 * 
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public static Key getPriveKey(String file) throws Exception {
		FileInputStream fis = new FileInputStream(file);
		ObjectInputStream ois = new ObjectInputStream(fis);
		Key key = (Key) ois.readObject();
		ois.close();
		return key;
	}
}

/** 加密后的byte不能直接new string否则不能对形成的string解密，需要进行Base64编码 */
